package com.woniu.car.controller;

import com.woniu.car.code.ESProperties;
import com.woniu.car.common.ResponseEntity;
import com.woniu.car.config.ElasticSearchGoodsEntity;
import com.woniu.car.config.ElasticSearchServerEntity;
import com.woniu.car.config.ElasticSearchShopEntity;
import com.woniu.car.exception.StatisticsException;
import com.woniu.car.parameter.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@Api(tags = "ElasticSearch控制层")
public class ElasticSearchController {
    @Autowired
    private ElasticsearchRestTemplate template;
    private static final String copy_to = "full_search" ;
    private static final String shopIndex = "shop";
    private static final String serverIndex = "server";
    private static final String goodsIndex = "goods";
    @PostMapping("/ElasticGoodsAdd")
    @ApiOperation("商品新增")
    public ResponseEntity ElasticGoodsAdd(@Validated ElasticGoodsAddParameter parameter) throws StatisticsException {
        
        if(null!=template.get(parameter.getGoodsNo(),ElasticSearchGoodsEntity.class))
            throw new StatisticsException(ESProperties.NOTNULLGOODSMSG);
        ElasticSearchGoodsEntity entity = new ElasticSearchGoodsEntity();
        BeanUtils.copyProperties(parameter,entity);
        entity.setId(parameter.getGoodsNo());
        template.save(entity);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    @GetMapping("/ElasticGoodsSearch")
    @ApiOperation("搜索商品")
    public ResponseEntity ElasticGoodsSearch(String search) throws StatisticsException {
        if(null==search)
            throw new StatisticsException(ESProperties.NOSEARCHMSG);
        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder(copy_to, search)).build();
        List<SearchHit<ElasticSearchGoodsEntity>> list = template.search(build, ElasticSearchGoodsEntity.class).getSearchHits();
        if (list.size()==0)
            throw new StatisticsException(ESProperties.NULLMSG);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG)
                .setObject(list);
    }
    @PutMapping("/ElasticGoodsUpdate")
    @ApiOperation("根据编号更新商品")
    public ResponseEntity ElasticGoodsUpdate(ElasticGoodsUpdateParameter parameter) throws StatisticsException {
        ElasticSearchGoodsEntity entity = template.get(parameter.getGoodsNo(), ElasticSearchGoodsEntity.class);
        if(null==entity)
            throw new StatisticsException(ESProperties.NOTNULLTHISMSG);
        Document document = Document.create();
        if(null!=parameter.getGoodsNo())
            document.put("goodsNo",parameter.getGoodsNo());
        if(null!=parameter.getGoodsName())
            document.put("goodsName",parameter.getGoodsName());
        if(null!=parameter.getCategoryName())
            document.put("categoryName",parameter.getCategoryName());
        if(null!=parameter.getDescription())
            document.put("description",parameter.getDescription());
        if(null!=parameter.getImage())
            document.put("image",parameter.getImage());
        if(null!=parameter.getGoodsPrice())
            document.put("goodsPrice",parameter.getGoodsPrice());
        if(null!=parameter.getSpecName())
            document.put("specName",parameter.getSpecName());
        if(null!=parameter.getSpecValue())
            document.put("specValue",parameter.getSpecValue());
        template.update(UpdateQuery.builder(parameter.getGoodsNo())
                        .withDocument(document)
                        .build(),
                IndexCoordinates.of(goodsIndex));
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    @DeleteMapping("/ElasticGoodsDelete")
    @ApiOperation("根据编号删除索引信息")
    public ResponseEntity ElasticGoodsDelete(String goodsNo) throws StatisticsException {
        if(null==goodsNo)
            throw new StatisticsException(ESProperties.NOIDMSG);
        if (null==template.get(goodsNo, ElasticSearchGoodsEntity.class)) 
            throw new StatisticsException(ESProperties.NULLDELETEMSG);
        template.delete(goodsNo,ElasticSearchGoodsEntity.class);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    @PostMapping("/ElasticServerAdd")
    @ApiOperation("服务新增")
    public  ResponseEntity ElasticServerAdd(@Validated ElasticServerAddParameter parameter) throws StatisticsException {
        System.out.println(parameter);
//        .must(QueryBuilders.termQuery("shopId", parameter.getShopId())
//                        .must(QueryBuilders.termQuery("serviceName",parameter.getServiceName()))
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .withQuery(new BoolQueryBuilder()
                            .must(new MatchQueryBuilder("shopId",parameter.getShopId()))
                            .must(new MatchQueryBuilder("serviceName",parameter.getServiceName()))
                ).build();
        List<SearchHit<ElasticSearchServerEntity>> list = template.search(build, ElasticSearchServerEntity.class).getSearchHits();
        System.out.println(build);
        System.out.println(list);
        if(list.size()>0)
            throw new StatisticsException(ESProperties.NOTNULLSERVERMSG);
        ElasticSearchServerEntity entity = new ElasticSearchServerEntity();
        BeanUtils.copyProperties(parameter,entity);
        template.save(entity);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    @GetMapping("/ElasticServerSearchById")
    @ApiOperation("根据商店id查询服务")
    public ResponseEntity elasticServerSearchById(String shopId) throws StatisticsException{
        if(null==shopId)
            throw new StatisticsException(ESProperties.NOSEARCHMSG);
        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder("shopId", shopId)).build();
        List<SearchHit<ElasticSearchServerEntity>> list = template.search(build, ElasticSearchServerEntity.class).getSearchHits();
        if(list.size()==0)
            throw new StatisticsException(ESProperties.NULLMSG);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG)
                .setObject(list);
    }
    @GetMapping("/ElasticServerSearch")
    @ApiOperation("根据copyTo字段查询服务")
    public ResponseEntity elasticServerSearch(String search) throws StatisticsException{
        if(null==search)
            throw new StatisticsException(ESProperties.NOSEARCHMSG);
        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder(copy_to, search)).build();
        List<SearchHit<ElasticSearchServerEntity>> list = template.search(build, ElasticSearchServerEntity.class).getSearchHits();
        if(list.size()==0)
            throw new StatisticsException(ESProperties.NULLMSG);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG)
                                    .setObject(list);
    }
    //更新shop索引库
    @PutMapping("/ElasticServerUpdate")
    @ApiOperation("根据传入的商铺Id查询提供的服务以及描述")
    public ResponseEntity ElasticServerUpdate(@Validated ElasticServerUpdateParameter parameter) throws StatisticsException {
        Document document = Document.create();
        System.out.println(parameter);
        if(null!=parameter.getServiceName())
            document.put("serviceName",parameter.getServiceName());
        if(null!=parameter.getDescription())
            document.put("description",parameter.getDescription());
//        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder("shopId", parameter.getShopId())).build();
//        List<SearchHit<ElasticSearchServerEntity>> list = template.search(build, ElasticSearchServerEntity.class).getSearchHits();
//        if(list.size()==0)
//            throw new StatisticsException(ESProperties.NULLUPDATEMSG);
        UpdateResponse update = template.update(UpdateQuery.builder(parameter.getReceiverId())
                        .withDocument(document)
                        .build(),
                IndexCoordinates.of(serverIndex));
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    @DeleteMapping("/ElasticServerDelete")
    @ApiOperation("根据传入的数据店铺id删除索引库信息")
    public ResponseEntity ElasticServerDelete(Integer receiverId) throws StatisticsException {
        if(null==receiverId)
            throw new StatisticsException(ESProperties.NULLIDMSG);
        if(receiverId<0)
            throw new StatisticsException(ESProperties.NOIDMSG);
        if(null==template.get(receiverId.toString(),ElasticSearchServerEntity.class))
            throw new StatisticsException(ESProperties.NULLDELETEMSG);
//        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder("shopId", shopId)).build();
//        List<SearchHit<ElasticSearchServerEntity>> list = template.search(build, ElasticSearchServerEntity.class).getSearchHits();
//        if(list.size()==0)
//            throw new StatisticsException(ESProperties.NULLDELETEMSG);
//        SearchHit<ElasticSearchServerEntity> hit = list.get(0);
        template.delete(receiverId.toString(), ElasticSearchServerEntity.class);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    
    @PostMapping("/ElasticShopAdd")
    @ApiOperation("新增商铺信息")
    public ResponseEntity ElasticShopAdd(@Validated ElasticShopAddParameter parameter) throws StatisticsException {
        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder("id", parameter.getId()))
                .withQuery(new MatchQueryBuilder("shopName",parameter.getShopName()))
                .build();
        List<SearchHit<ElasticSearchServerEntity>> list = template.search(build, ElasticSearchServerEntity.class).getSearchHits();
        if(list.size()>0)
            throw new StatisticsException(ESProperties.NOTNULLSHOPMSG);
        ElasticSearchShopEntity entity = new ElasticSearchShopEntity();
        BeanUtils.copyProperties(parameter,entity);
        template.save(entity);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    //查询shop索引库
    @GetMapping("/ElasticShopSearch")
    @ApiOperation("通过copyTo共同字段查询商铺信息")
    public ResponseEntity ElasticShopSearch(String search) throws StatisticsException {
        if(null==search)
            throw new StatisticsException(ESProperties.NOSEARCHMSG);
        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(new MatchQueryBuilder(copy_to, search)).build();
        SearchHits<ElasticSearchShopEntity> search1 = template.search(build, ElasticSearchShopEntity.class);
        List<SearchHit<ElasticSearchShopEntity>> list = search1.getSearchHits();
        if (list.size()==0)
            throw new StatisticsException(ESProperties.NULLMSG);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG)
                .setObject(list);
    }
    //更新shop索引库
    @PutMapping("/ElasticShopUpdate")
    @ApiOperation("根据传入商铺Id更新商铺信息")
    public ResponseEntity ElasticShopUpdate(@Validated ElasticShopUpdateParameter parameter) throws StatisticsException {
        Document document = Document.create();
        if(null==template.get(parameter.getId().toString(),ElasticSearchShopEntity.class))
            throw new StatisticsException(ESProperties.NULLMSG);
        if(null!=parameter.getShopName())
            document.put("shopName",parameter.getShopName());
        if(null!=parameter.getShopDesc())
            document.put("shopDesc",parameter.getShopDesc());
        if(null!=parameter.getShopAddr())
            document.put("shopAddr",parameter.getShopAddr());
        if(null!=parameter.getLongitudeAndShopLatitude())
            document.put("longitudeAndShopLatitude",parameter.getLongitudeAndShopLatitude());
        if(null!=parameter.getShopPictureUrl())
            document.put("shopPictureUrl",parameter.getShopPictureUrl());
        if(null!=parameter.getBusinessTime())
            document.put("businessTime",parameter.getBusinessTime());
        if(null!=parameter.getShopScore())
            document.put("businessTime",parameter.getBusinessTime());
        UpdateResponse update = template.update(UpdateQuery.builder(parameter.getId().toString())
                        .withDocument(document)
                        .build(),
                IndexCoordinates.of(shopIndex));
 
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }
    
    @DeleteMapping("/ElasticShopDelete")
    @ApiOperation("根据传入商铺Id删除商铺信息")
    public ResponseEntity ElasticSearchShopDelete(Integer shopId) throws StatisticsException {
        if(null==shopId)
            throw new StatisticsException(ESProperties.NULLIDMSG);
        if(shopId<0)
            throw new StatisticsException(ESProperties.NOIDMSG);
        if (null==template.get(shopId.toString(),ElasticSearchShopEntity.class))
            throw new StatisticsException(ESProperties.NULLDELETEMSG);
        template.delete(shopId.toString(), ElasticSearchShopEntity.class);
        return new ResponseEntity().setCode(ESProperties.SUCCESSCODE).setMsg(ESProperties.SUCCESSMSG);
    }


}
